import cors from 'cors';
import { Request, Response, NextFunction } from 'express';
import logger from '../utils/logger';
import { parseEnvArray } from '../utils/envParser';

// CORS配置选项
interface CorsConfig {
  origins: string[];
  credentials: boolean;
  optionsSuccessStatus: number;
  maxAge: number;
  allowedHeaders: string[];
  allowedMethods: string[];
}

// 默认CORS配置
const defaultCorsConfig: CorsConfig = {
  origins: [
    'http://localhost:3000',
    'http://localhost:3001',
    'http://localhost:8080',
    'http://localhost:8081',
    'http://127.0.0.1:3000',
    'http://127.0.0.1:8080',
    'file://', // 支持本地HTML文件
  ],
  credentials: true,
  optionsSuccessStatus: 200,
  maxAge: 86400, // 24小时
  allowedHeaders: [
    'Origin',
    'X-Requested-With',
    'Content-Type',
    'Accept',
    'Authorization',
    'X-API-Key',
    'X-Client-Version',
    'Cache-Control',
  ],
  allowedMethods: [
    'GET',
    'POST',
    'PUT',
    'DELETE',
    'PATCH',
    'OPTIONS',
    'HEAD',
  ],
};

// 获取CORS配置
function getCorsConfig(): CorsConfig {
  const envOrigins = parseEnvArray(process.env.ALLOWED_ORIGINS);
  
  return {
    ...defaultCorsConfig,
    origins: envOrigins.length > 0 ? envOrigins : defaultCorsConfig.origins,
  };
}

// 动态origin检查函数
function corsOriginHandler(origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) {
  const config = getCorsConfig();
  
  // 允许没有origin的请求（如移动应用、Postman等）
  if (!origin) {
    logger.debug('CORS: 允许无origin请求');
    return callback(null, true);
  }

  // 检查origin是否在允许列表中
  const isAllowed = config.origins.some(allowedOrigin => {
    // 支持通配符匹配
    if (allowedOrigin === '*') return true;
    
    // 支持本地文件协议
    if (allowedOrigin === 'file://' && origin.startsWith('file://')) return true;
    
    // 精确匹配
    if (allowedOrigin === origin) return true;
    
    // 支持子域名匹配（如 *.example.com）
    if (allowedOrigin.startsWith('*.')) {
      const domain = allowedOrigin.slice(2);
      return origin.endsWith(domain);
    }
    
    return false;
  });

  if (isAllowed) {
    logger.debug(`CORS: 允许来源 ${origin}`);
    callback(null, true);
  } else {
    logger.warn(`CORS: 拒绝来源 ${origin}`);
    callback(new Error(`CORS策略阻止了来自 ${origin} 的请求`), false);
  }
}

// 创建CORS中间件
export const corsMiddleware = cors({
  origin: corsOriginHandler,
  credentials: true,
  optionsSuccessStatus: 200,
  maxAge: 86400,
  allowedHeaders: defaultCorsConfig.allowedHeaders,
  methods: defaultCorsConfig.allowedMethods,
  preflightContinue: false,
});

// 手动CORS中间件（用于特殊情况）
export const manualCorsMiddleware = (req: Request, res: Response, next: NextFunction) => {
  const config = getCorsConfig();
  const origin = req.headers.origin;

  // 设置基本的CORS头
  if (origin && config.origins.includes(origin)) {
    res.header('Access-Control-Allow-Origin', origin);
  } else if (config.origins.includes('*')) {
    res.header('Access-Control-Allow-Origin', '*');
  }

  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Access-Control-Allow-Methods', config.allowedMethods.join(', '));
  res.header('Access-Control-Allow-Headers', config.allowedHeaders.join(', '));
  res.header('Access-Control-Max-Age', config.maxAge.toString());

  // 处理预检请求
  if (req.method === 'OPTIONS') {
    res.status(200).end();
    return;
  }

  next();
};

// 开发环境宽松CORS中间件
export const devCorsMiddleware = (req: Request, res: Response, next: NextFunction) => {
  if (process.env.NODE_ENV === 'development') {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD');
    res.header('Access-Control-Allow-Headers', '*');
    res.header('Access-Control-Max-Age', '86400');

    if (req.method === 'OPTIONS') {
      res.status(200).end();
      return;
    }
  }

  next();
};

// 获取当前CORS配置信息
export const getCorsInfo = () => {
  const config = getCorsConfig();
  return {
    allowedOrigins: config.origins,
    credentials: config.credentials,
    allowedMethods: config.allowedMethods,
    allowedHeaders: config.allowedHeaders,
    maxAge: config.maxAge,
  };
};

// 验证CORS配置
export const validateCorsConfig = () => {
  const config = getCorsConfig();
  
  logger.info('CORS配置验证:');
  logger.info(`- 允许的来源: ${config.origins.join(', ')}`);
  logger.info(`- 允许凭据: ${config.credentials}`);
  logger.info(`- 允许的方法: ${config.allowedMethods.join(', ')}`);
  logger.info(`- 缓存时间: ${config.maxAge}秒`);
  
  if (config.origins.includes('*') && config.credentials) {
    logger.warn('⚠️  安全警告: 不建议在允许凭据的同时使用通配符origin');
  }
  
  if (process.env.NODE_ENV === 'production' && config.origins.includes('*')) {
    logger.warn('⚠️  生产环境警告: 不建议在生产环境使用通配符origin');
  }
};

export default corsMiddleware; 